/**
 * 数据绑定：<div :width="prop"></div>
 * 显示隐藏：<div :if="prop"></div>
 * 显示隐藏：<div :show="prop"></div>
 * bool 绑定：<div :b.is-empty="prop"></div>
 * style 绑定：<div :s.color="prop"></div>
 * class 绑定：<div :c.show="prop"></div>
 * class 绑定：<div :class="prop"></div>
 * 事件绑定：<div @focus="$focus"></div>      回调函数定义在 instance 上
 * 事件绑定：<div @click="listener"></div>       回调函数定义在 instance.$listener 上
 * 节点注册：<div ref="div"></div>
 */

const { default: parser } = require('posthtml-parser')

const EACH_RESULT = {
  DELETE: 0,
  BREAK: 1,
  DELETE_AND_BREAK: 2,
}

function eachArray(target, callback) {
  for (let index = 0; index < target.length; index++) {
    const result = callback(target[index], index, target)
    if (result === EACH_RESULT.DELETE) {
      target.splice(index--, 1)
    } else if (result === EACH_RESULT.DELETE_AND_BREAK) {
      target.splice(index--, 1)
      break
    } else if (result === EACH_RESULT.BREAK) {
      break
    }
  }
}

module.exports = function (content, map) {
  debugger
  const ast = parser(content)

  const BIND = /^:\w+/
  const BIND_ATTR = /^:[a-z]+(-[a-z]+)*$/
  const BIND_STYLE_ATTR = /^:s\.[a-z]+(-[a-z]+)*$/
  const BIND_CLASS_ATTR = /^:c\.[a-z]+(-[a-z]+)*$/
  const BIND_BOOL_ATTR = /^:b\.[a-z]+(-[a-z]+)*$/
  const EVENT = /^@[a-z]+$/
  const TEMPLATE_LITERAL = /\{\{\s*.+\s*\}\}/

  function filter(value, key, map) {
    const t = typeof value
    if (t === 'string') {
      value = value.trim()
      if (value.length) {
        Reflect.set(map, key, {
          tag: '#text',
          data: value,
          bind: TEMPLATE_LITERAL.test(value), // 是一个字符串模板
        })
      } else {
        return EACH_RESULT.DELETE
      }
    } else if (t === 'object') {
      filterTag(value)
    }
  }

  function filterTag(tag) {
    for (let tagKey in tag) {
      // 处理 tag attribute
      if (tagKey === 'attrs') {
        const bind = {
          default: {}, // 普通的 attribute
          style: {},
          class: {},
          event: {},
          bool: {},
        }
        const count = {
          default: 0,
          style: 0,
          class: 0,
          event: 0,
          bool: 0,
        }
        let attrCount = 0
        // 遍历 attribute 集合
        for (let attrKey in tag.attrs) {
          attrCount++
          const attrVal = tag.attrs[attrKey]
          // ref 注册
          if (attrKey === 'ref') {
            tag.ref = attrVal
            Reflect.deleteProperty(tag.attrs, attrKey)
            continue
          }
          // 需要进行双向绑定的 attitude
          if (BIND.test(attrKey)) {
            Reflect.deleteProperty(tag.attrs, attrKey)
            // style attribute
            if (BIND_STYLE_ATTR.test(attrKey)) {
              count.style++
              bind.style[attrKey.slice(3)] = attrVal
              continue
            }
            // class attribute
            if (BIND_CLASS_ATTR.test(attrKey)) {
              count.class++
              bind.class[attrKey.slice(3)] = attrVal
              continue
            }
            // boolean 类型值的 attribute
            if (BIND_BOOL_ATTR.test(attrKey)) {
              count.bool++
              bind.bool[attrKey.slice(3)] = attrVal
              continue
            }
            // 普通的 attribute 双向绑定
            if (BIND_ATTR.test(attrKey)) {
              count.default++
              bind.default[attrKey.slice(1)] = attrVal
              continue
            }
          }
          // 事件绑定
          if (EVENT.test(attrKey)) {
            count.event++
            Reflect.deleteProperty(tag.attrs, attrKey)
            bind.event[attrKey.slice(1)] = attrVal
            continue
          }
        }
        if (count.default) {
          tag.bind = bind.default
        }
        if (count.style) {
          tag.style = bind.style
        }
        if (count.class) {
          tag.classList = bind.class
        }
        if (count.event) {
          tag.event = bind.event
        }
        if (count.bool) {
          tag.bool = bind.bool
        }
        if (Object.values(count).reduce((m, n) => m + n) === attrCount) {
          Reflect.deleteProperty(tag, 'attrs')
        }
      }

      // 处理 tag children
      if (tagKey === 'content') {
        // 过滤
        eachArray(tag.content, filter)
        // 重命名
        if (tag.content.length) {
          tag.children = tag[tagKey]
        }
        // 剔除
        Reflect.deleteProperty(tag, tagKey)
      }
    }
  }

  eachArray(ast, filter)

  return `module.exports = ${JSON.stringify(ast)}`
}
